﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using PortalWeb.Core.IDao;
using PortalWeb.Core.IManager;

namespace PortalWeb.Business.Manager
{
    public abstract class BaseService<T> : IGenericManager<T> where T : class, new()
    {
        //当前仓储
        public IBaseRepository<T> BaseRepository { get; set; }
        //为了职责单一的原则，将获取线程内唯一实例的DbSession的逻辑放到工厂里面去了

        public T Get(object id)
        {
            var entity = BaseRepository.Find(id);
            return entity;
        }

        //实现对数据库的添加功能
        public T Add(T entity)
        {
            //调用T对应的仓储来做添加工作
          var i =  BaseRepository.Add(entity);
            if (i > 0)
            {
                return entity;
            }
            else
            {
                return null;
            }
        }

        //实现对数据的修改功能
        public bool Update(T entity)
        {
            return BaseRepository.Update(entity);

        }

        //实现对数据库的删除功能
        public bool Delete(T entity)
        {
            return BaseRepository.Delete(entity);
        }

        public int Count()
        {
            return BaseRepository.Count();
        }

        //实现对数据库的查询  --简单查询
        public IEnumerable<T> LoadEntities(Expression<Func<T, bool>> whereLambda)
        {
            return BaseRepository.Find(whereLambda);
        }

        public async Task<T[]> LoadEntitiesAsync(Expression<Func<T, bool>> whereLambda)
        {
            var result = await BaseRepository.FindAsync(whereLambda);
            return result.ToArray();
        }

        public async Task<T> GetAsync(object id)
        {
            var entity = await BaseRepository.FindAsync(id);
            return entity;
        }

        public async Task<T[]> LoadAllEntitiesnAsync()
        {
            var result = await BaseRepository.FindAllAsync();
            return result.ToArray();
        }

        public async Task<T[]> LoadPageEntitiesAsync<TS>(Expression<Func<T, bool>> whereLambda, bool b, Expression<Func<T, TS>> orderByLambda, int offset, int limint)
        {
            var result = await BaseRepository.FindAsync(whereLambda);
            return result.ToArray();
        }
        public async Task<T[]> LoadPageEntitiesAsync(Expression<Func<T, bool>> whereLambda, string order, string sort, int offset, int limit)
        {
            var result = await BaseRepository.FindAsync(whereLambda);
            return result.ToArray();
        }

        public T[] LoadPageEntities<TS>(Expression<Func<T, bool>> whereLambda, bool isAsc, Expression<Func<T, TS>> orderByLambda, int offset, int limit)
        {
            return  BaseRepository.LoadPageEntities(whereLambda,  isAsc,  orderByLambda,  offset,  limit);
        }

        public T[] LoadPageEntities(Expression<Func<T, bool>> whereLambda, string order, string sort, int offset, int limit)
        {
            return  BaseRepository.LoadPageEntities(whereLambda, order,  sort,  offset,  limit);
        }

        public virtual async Task<IdentityResult> CreateAsync(T entity)
        {
            this.ThrowIfDisposed();
            await BaseRepository.AddAsync(entity);
            return IdentityResult.Success;
        }

        public virtual async Task<IdentityResult> UpdateAsync(T entity)
        {
            this.ThrowIfDisposed();
             await BaseRepository.UpdateAsync(entity);
            return IdentityResult.Success;
        }

        public virtual async Task<IdentityResult> DeleteAsync(T entity)
        {
            this.ThrowIfDisposed();
             await BaseRepository.DeleteAsync(entity);
            return IdentityResult.Success;
        }

        protected void ThrowIfDisposed()
        {
            if (this._disposed)
            {
                throw new ObjectDisposedException("BaseService");
            }
        }

        private bool _disposed;

        public void Dispose()
        {
            this.Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing && !this._disposed)
            {
                this.BaseRepository.Dispose();
                this._disposed = true;
            }
        }
    }
}
